package com.woniuxy.list.service.impl;

import com.hc.entity.RankList;
import com.woniuxy.list.mapper.ListMapper;
import com.woniuxy.list.service.ListService;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class ListServiceImpl implements ListService {
    @Resource
    private ListMapper listMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    //给榜单修改次数加1
    //只要榜单的数据发生变化都会加1
    public int updateCount(int flag){
        //榜单表修改次数
        Integer updateCount = (Integer) redisTemplate.opsForValue().get("updateCount");
        if(updateCount==null){
            //没有，就新建一个
            redisTemplate.opsForValue().set("updateCount",1);
        }else {
            //有则次数加1
            redisTemplate.opsForValue().increment("updateCount");
        }
        return flag;
    }
    @Override
    public int addList(RankList rankList) {
        int flag = listMapper.addList(rankList);
        if(flag>0){
            return updateCount(flag);
        }
        return 0;
    }
    @Override
    public int updateScoreByListId(Integer id, Integer score) {
        int flag = listMapper.updateScoreByListId(id, score);
        if(flag>0){
            return updateCount(flag);
        }
        return 0;
    }

    @Override
    public List<RankList> getAllList() {
        List<RankList> result=new ArrayList<>();
        Integer updateCount=(Integer) redisTemplate.opsForValue().get("updateCount");
        Integer allCurrentCount=(Integer)redisTemplate.opsForValue().get("allCurrentCount");
        if(updateCount.intValue()!=allCurrentCount.intValue()){
            //不相等
            List<RankList> rankLists=listMapper.getAllList();
            if(rankLists.size()>0){
                //往zset中添加数据，防止zset不存在
                redisTemplate.opsForZSet().add("allRankList","s",1);
                //移除当前zset中的所有数据
                redisTemplate.opsForZSet().removeRange("allRankList",0,-1);
                for(RankList rankList:rankLists){
                    redisTemplate.opsForZSet().add("allRankList",rankList,rankList.getScore());
                }
                Set<Object> allRankList = redisTemplate.opsForZSet().reverseRange("allRankList", 0, -1);
                for(Object o:allRankList){
                    result.add((RankList) o);
                }
                //将updateCount的值赋给allCurrentCount
                redisTemplate.opsForValue().set("allCurrentCount",updateCount);
            }
            return result;
        }
        Set<Object> allRankList = redisTemplate.opsForZSet().reverseRange("allRankList", 0, -1);
        for(Object o:allRankList){
            result.add((RankList) o);
        }
        return result;
    }

    @Override
    public List<RankList> getListByClassId(Integer cid) {
        List<RankList> list=new ArrayList<>();
        Integer updateCount=(Integer) redisTemplate.opsForValue().get("updateCount");
        Integer classCurrentCount = (Integer)redisTemplate.opsForValue().get("classCurrentCount");

        if(!updateCount.equals(classCurrentCount)){
            //不相等
            List<RankList> listByClassId = listMapper.getListByClassId(cid);
            if(listByClassId.size()>0){
                redisTemplate.opsForZSet().add(cid+"classRankList","s",1);
                redisTemplate.opsForZSet().removeRange(cid+"classRankList",0,-1);
                for(RankList rankList:listByClassId){
                    redisTemplate.opsForZSet().add(cid+"classRankList",rankList,rankList.getScore());
                }
                Set<Object> reverseRange = redisTemplate.opsForZSet().reverseRange(cid+"classRankList", 0, -1);
                for(Object o:reverseRange){
                    list.add((RankList)o);
                }
                redisTemplate.opsForValue().set("classCurrentCount",updateCount);
            }
            return list;
        }
        //相等
        Long count = redisTemplate.opsForZSet().zCard(cid+"classRankList");
        System.out.println(count);
        if(count==0){
            //表示该种类的榜单还未存到redis中
            List<RankList> listByClassId = listMapper.getListByClassId(cid);
            if(listByClassId.size()>0){
                for(RankList rankList:listByClassId){
                    redisTemplate.opsForZSet().add(cid+"classRankList",rankList,rankList.getScore());
                }
                Set<Object> reverseRange = redisTemplate.opsForZSet().reverseRange(cid+"classRankList", 0, -1);
                for(Object o:reverseRange){
                    list.add((RankList)o);
                }
            }
            return list;
        }
        //相等且Redis中有数据
        Set<Object> reverseRange = redisTemplate.opsForZSet().reverseRange(cid+"classRankList", 0, -1);
        for(Object o:reverseRange){
            list.add((RankList)o);
        }
        return list;
    }
}
